#ifndef _COMPLEXMAT_
#define _COMPLEXMAT_

#include "complex.h"
#include "complexVec.h"
#include <vl/VLd.h>
#include <vector>

using namespace std;

namespace moremath{

	class Matc{
	protected:
		vector<Vecc> mMat;
		int mNumRows;
		int mNumCols;
	public:
		Matc(Matd _re, Matd _im){
			mNumRows = _re.Rows();
			mNumCols = _re.Cols();
			mMat.resize(mNumRows);
			for(int i=0; i<mNumRows; i++){
				mMat[i].SetSize(mNumCols);
				for(int j=0; j<mNumCols; j++){
					mMat[i][j] = complex(_re[i][j], _im[i][j]);
				}
			}
		}
		Matc(int _r, int _c){
			mNumRows = _r;
			mNumCols = _c;
			mMat.resize(mNumRows);
			for(int i=0; i<mNumRows; i++) mMat[i].SetSize(mNumCols);
		}
		Matc(){
			mNumRows = 0;
			mNumCols = 0;
			mMat.clear();
		}

		Matd re();
		Matd im();
		void setReal(Matd &_real);
		void setImag(Matd &_imag);
		inline int Rows(){return mNumRows;}
		inline int Cols(){return mNumCols;}

		// returns the row
		inline Vecc& operator[] (int i){return mMat[i];}	// indexing operator
		// returns the col
		Vecc getCol(int _i);
		void setCol(int _i, Vecc _c);

		void operator = (Matc _v);	// assign one to other
		Matc operator + (Matc& _v);
		void operator += (Matc& _v);
		Matc operator - ();
		Matc operator * (double);	// multiplies with a scalar
		Matc operator * (complex _q);	// multiplies with a complex num
		void operator *= (double);	// multiplies with a scalar
		Matc operator / (double);	// divides by a number

		Vecc operator * (Vecc &_v);	// mat vec multiplication
		Vecc operator * (Vecd &_v);	// mat vec multiplication
		Matc operator * (Matc &_v);

		Matc conj();	// returns the complex conjugate
	};

}

moremath::Matc operator * (moremath::Matc &_m1, Matd &_m2);	// mat mat multiplication
moremath::Matc operator * (Matd &_m2, moremath::Matc &_m1);	// mat mat multiplication
moremath::Matc trans(moremath::Matc &_m);
moremath::Vecc diag(moremath::Matc &_m);


#endif
